﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sicurezza.CA.DataProvider;
using Sicurezza.CA.Entita;
using OpenSSL.X509;
using OpenSSL.Core;
using OpenSSL.Crypto;
using Sicurezza.Entita;

namespace Sicurezza.CA.Manager
{
    public class RenewManager
    {

        private static RenewDataProvider dataProvider = new RenewDataProvider();
        public static string Check(string ReqId)
        {
            return dataProvider.Check(int.Parse(ReqId.Replace("ren-", "")));
        }

        public static string SaveRequest(string serial, string newkey)
        {
            int RenId = dataProvider.SaveRequest(serial);
            FileManager.SaveRenew(RenId, newkey);
            return "ren-" + RenId;
        }

        public static List<Request> GetWaiting()
        {
            return dataProvider.GetWaiting();
        }

        public static string Get(string RenId)
        {
            X509Certificate c = GetFromRenId(RenId);
            return c.ToString();
        }

        public static void Reject(string ReqId, string reason)
        {
            dataProvider.SetState(Convert.ToInt32(ReqId.Replace("ren-", "")), RequestState.Refused, reason.Replace("'", "''"));
        }

        public static X509Certificate GetFromRenId(string RenId)
        {
            int CertificateSerial = dataProvider.Get(RenId);
            string cert = FileManager.LoadCertificate(CertificateSerial);
            X509Certificate c = new X509Certificate(new BIO(cert));
            return c;
        }

        public static void Accept(string RenId, int days)
        {


            X509Certificate certificato = GetFromRenId(RenId);
            RevokeManager.ProcessRequest(certificato.SerialNumber.ToString());
            X509Request r = new X509Request();
            X509Name n = new X509Name();
            n.Common = certificato.Subject.Common;
            n.Organization = certificato.Subject.Organization;
            n.OrganizationUnit = certificato.Subject.OrganizationUnit;
            n.Country = certificato.Subject.Country;

            X509Extension keyUsage = certificato.Extensions.FirstOrDefault(x => x.Name.Equals("X509v3 Key Usage"));
            X509Extension mail = certificato.Extensions.FirstOrDefault(x => x.Name.Equals("X509v3 Subject Alternative Name"));
            string RequestKeyUsage = "";
            if (keyUsage != null)
            {
                string usage = keyUsage.ToString();
                bool digitalSignature = usage.Contains("Digital Signature");
                bool keyEncipherment = usage.Contains("Key Encipherment");
                if (digitalSignature && keyEncipherment)
                    RequestKeyUsage += "digitalSignature,keyEncipherment";
                else
                {
                    if (digitalSignature) RequestKeyUsage += "digitalSignature";
                    if (keyEncipherment) RequestKeyUsage += "keyEncipherment";
                }
                if (!string.IsNullOrEmpty(RequestKeyUsage))
                    n.AddEntryByName("keyUsage", RequestKeyUsage);
            }

            n.AddEntryByName("subjectAltName", mail.ToString());

            r.Subject = n;
            r.PublicKey = CryptoKey.FromPublicKey(FileManager.LoadRenew(Convert.ToInt32(RenId)),null);
            SSLManager.BuildCertificate("ren-"+RenId, r ,days);
            dataProvider.SetState(Convert.ToInt32(RenId.Replace("req-", "")), RequestState.Accepted);
        }
    }
}
